// Package service internal/service/role_service.go
package service

import (
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"github.com/jinzhu/copier"
	"gozrd-admin-api/internal/entity/dto"
	"gozrd-admin-api/internal/entity/model"
	"gozrd-admin-api/internal/repository"
	"gozrd-admin-api/pkg/response"
)

// IRoleService 角色服务接口
type IRoleService interface {
	CreateSysRole(c *gin.Context, dto dto.AddSysRoleDto)
	GetSysRoleById(c *gin.Context, id int)
	UpdateSysRole(c *gin.Context, dto dto.UpdateSysRoleDto)
	DeleteSysRoleById(c *gin.Context, dto dto.SysRoleIdDto)
	UpdateSysRoleStatus(c *gin.Context, dto dto.UpdateSysRoleStatusDto)
	GetSysRoleList(c *gin.Context, pageNum, pageSize int, roleName, status, beginTime, endTime string)
	QuerySysRoleVoList(c *gin.Context)
	QueryRoleMenuIdList(c *gin.Context, id int)
	AssignPermissions(c *gin.Context, menu dto.RoleMenu)
}

// RoleServiceImpl 角色服务实现
type RoleServiceImpl struct {
	roleRepository repository.IRoleRepository
	validator      *validator.Validate
}

// NewRoleService 创建角色服务实例
func NewRoleService(roleRepo repository.IRoleRepository) IRoleService {
	return &RoleServiceImpl{
		roleRepository: roleRepo,
		validator:      validator.New(),
	}
}

// CreateSysRole 创建角色
func (s *RoleServiceImpl) CreateSysRole(c *gin.Context, roleDTO dto.AddSysRoleDto) {
	// 验证DTO
	if err := s.validator.Struct(roleDTO); err != nil {
		response.Fail(c, response.ErrParams, err.Error())
		return
	}

	// DTO转换为领域模型
	role := model.SysRole{
		RoleName:    roleDTO.RoleName,
		RoleKey:     roleDTO.RoleKey,
		Status:      roleDTO.Status,
		Description: roleDTO.Description,
	}

	// 调用Repository层
	err := s.roleRepository.CreateSysRole(role)
	if err != nil {
		if err == repository.RoleNameExist {
			response.Fail(c, response.BadRequest, "角色名称已存在")
			return
		}
		if err == repository.RoleKeyExist {
			response.Fail(c, response.BadRequest, "角色标识已存在")
			return
		}
		response.Fail(c, response.ErrDatabase, "创建角色失败："+err.Error())
		return
	}

	response.SuccessWithMessage(c, "创建成功", nil)
}

// GetSysRoleById 根据id查询角色
func (s *RoleServiceImpl) GetSysRoleById(c *gin.Context, id int) {
	// 调用Repository层
	role, err := s.roleRepository.GetSysRoleById(id)
	if err != nil {
		response.Fail(c, response.ErrDatabase, "获取角色详情失败："+err.Error())
		return
	}

	response.Success(c, role)
}

// UpdateSysRole 修改角色
func (s *RoleServiceImpl) UpdateSysRole(c *gin.Context, roleDTO dto.UpdateSysRoleDto) {
	// 验证DTO
	if err := s.validator.Struct(roleDTO); err != nil {
		response.Fail(c, response.ErrParams, err.Error())
		return
	}

	// DTO转换为领域模型
	role := model.SysRole{
		ID:          uint(roleDTO.Id),
		RoleName:    roleDTO.RoleName,
		RoleKey:     roleDTO.RoleKey,
		Status:      roleDTO.Status,
		Description: roleDTO.Description,
	}

	// 调用Repository层
	updatedRole, err := s.roleRepository.UpdateSysRole(role)
	if err != nil {
		response.Fail(c, response.ErrDatabase, "更新角色失败："+err.Error())
		return
	}

	response.Success(c, updatedRole)
}

// DeleteSysRoleById 删除角色
func (s *RoleServiceImpl) DeleteSysRoleById(c *gin.Context, dto dto.SysRoleIdDto) {
	// 验证DTO
	if err := s.validator.Struct(dto); err != nil {
		response.Fail(c, response.ErrParams, err.Error())
		return
	}

	// 调用Repository层
	err := s.roleRepository.DeleteSysRoleById(dto.Id)
	if err != nil {
		response.Fail(c, response.ErrDatabase, "删除角色失败："+err.Error())
		return
	}

	response.Success(c, nil)
}

// UpdateSysRoleStatus 更新角色状态
func (s *RoleServiceImpl) UpdateSysRoleStatus(c *gin.Context, dto dto.UpdateSysRoleStatusDto) {
	// 验证DTO
	if err := s.validator.Struct(dto); err != nil {
		response.Fail(c, response.ErrParams, err.Error())
		return
	}

	// 调用Repository层
	err := s.roleRepository.UpdateSysRoleStatus(dto.Id, dto.Status)
	if err != nil {
		response.Fail(c, response.ErrDatabase, "更新角色状态失败："+err.Error())
		return
	}

	response.Success(c, nil)
}

// GetSysRoleList 查询角色列表
func (s *RoleServiceImpl) GetSysRoleList(c *gin.Context, pageNum, pageSize int, roleName, status, beginTime, endTime string) {
	// 参数校验
	if pageNum < 1 || pageSize < 1 {
		response.Fail(c, response.ErrParams, "分页参数错误")
		return
	}

	// 调用Repository层获取数据
	roles, total, err := s.roleRepository.GetSysRoleList(pageNum, pageSize, roleName, status, beginTime, endTime)
	if err != nil {
		response.Fail(c, response.ErrDatabase, "获取角色列表失败："+err.Error())
		return
	}

	// 构建分页结果
	result := map[string]interface{}{
		"total": total,
		"list":  roles,
	}

	response.Success(c, result)
}

// QuerySysRoleVoList 查询角色下拉列表
func (s *RoleServiceImpl) QuerySysRoleVoList(c *gin.Context) {
	// 调用Repository获取角色列表
	roles, err := s.roleRepository.QuerySysRoleList()
	if err != nil {
		response.Fail(c, response.ErrDatabase, "获取角色列表失败："+err.Error())
		return
	}

	// 转换为VO
	var roleVOs []dto.SysRoleVo
	if err := copier.Copy(&roleVOs, &roles); err != nil {
		response.Fail(c, response.ServerError, "数据转换失败")
		return
	}

	response.Success(c, roleVOs)
}

// QueryRoleMenuIdList 查询角色菜单权限ID列表
func (s *RoleServiceImpl) QueryRoleMenuIdList(c *gin.Context, id int) {
	// 调用Repository获取权限列表
	menuIds, err := s.roleRepository.QueryRoleMenuIdList(id)
	if err != nil {
		response.Fail(c, response.ErrDatabase, "获取角色菜单权限列表失败："+err.Error())
		return
	}

	// 转换为VO
	var idVos []dto.IdVo
	for _, id := range menuIds {
		idVos = append(idVos, dto.IdVo{Id: id})
	}

	response.Success(c, idVos)
}

// AssignPermissions 分配权限
func (s *RoleServiceImpl) AssignPermissions(c *gin.Context, menu dto.RoleMenu) {
	// 验证DTO
	if err := s.validator.Struct(menu); err != nil {
		response.Fail(c, response.ErrParams, err.Error())
		return
	}

	// 调用Repository层
	err := s.roleRepository.AssignPermissions(menu.Id, menu.MenuIds)
	if err != nil {
		response.Fail(c, response.ErrDatabase, "分配权限失败："+err.Error())
		return
	}

	response.SuccessWithMessage(c, "权限分配成功", nil)
}
